
(defun test-houses (houses)
  (let ((field (make-instance 'field :width 100 :depth 100)))
    (dolist (house houses field)
      (unless (place-house field house)
        (return-from test-houses nil)))))

(defun place-house (field house)
  (let ((position (find-position field house)))
    (when position
      (_place-house field house (first position) (second position)))))

(defun find-position (field house)
  (let ((vertical-counter (make-array (width field) :initial-element (depth field))))
    (dotimes (y (1+ (- (depth field) (depth house))))
      (let ((horizontal-counter (width field)))
        (dotimes (x (1+ (- (width field) (width house))))
          (cond ((eq 'house (aref (grid field) x y))
                 (setf (aref vertical-counter x) 0
                       horizontal-counter        0))
                ((eq 'vrijstand (aref (grid field) x y))
                 (incf horizontal-counter)
                 (incf (aref vertical-counter x)))
                ((eq 'empty (aref (grid field) x y))
                 (if (and (>= horizontal-counter (vrijstand house))
                          (>= (aref vertical-counter x) (vrijstand house))
                          (loop for _x from x to (min (1- (width field)) (+ x (width house) (vrijstand house)))
                             if (or (eq 'vrijstand (aref (grid field) _x y))
                                    (> (vrijstand house) (aref vertical-counter _x)))
                             do (return nil)
                             finally (return t)))
                     (return-from find-position (list x y))
                     (progn (incf horizontal-counter)
                            (incf (aref vertical-counter x)))))))))))

(defun _place-house (field house x y)
  (fill-rectangle (grid field)
                  (max 0 (- x (vrijstand house)))
                  (max 0 (- y (vrijstand house)))
                  (min (width field) 
                       (+ x (width house) (vrijstand house)))
                  (min (depth field)
                       (+ y (depth house) (vrijstand house)))
                  'vrijstand)
  (fill-rectangle (grid field) x y 
                  (+ x (width house))
                  (+ y (depth house))
                  'house))

(defun fill-rectangle (grid start-x start-y end-x end-y value)
  (format t "Placing ~a between (~d,~d) and (~d,~d)~%" value start-x start-y end-x end-y)
  (dotimes (x (- end-x start-x) t)
    (dotimes (y (- end-y start-y) t)
      (setf (aref grid (+ start-x x) (+ start-y y))
            value))))
